package com.angel.webapp.servlets;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import com.angel.architecture.exceptions.NonBusinessException;
import com.angel.common.keyValue.KeyValueResult;

/**
 * @author William
 * @since 03/February/2009
 */
public abstract class UploadServlet extends BaseAngelServlet{

	protected static final String DEFAULT_SEPARATOR_PARAMETERS = "*";

	private static final long serialVersionUID = -7427467996390884097L;

	private static final Logger LOGGER = Logger.getLogger(UploadServlet.class);

	protected abstract void doProcess(FileItem fileItem, KeyValueResult keyValueResult, final HttpServletRequest req, final HttpServletResponse res);

	@Override
	protected void process(KeyValueResult keyValueResult, final HttpServletRequest request, final HttpServletResponse response) {
		LOGGER.info("Building temporary directory.");
		File temporaryDirectory = this.buildTemporaryDirectory(keyValueResult);

		LOGGER.info("Getting files items to upload.");
		List<FileItem> fileItems = this.getFilesItems(temporaryDirectory, request);

		LOGGER.info("Processing files items [" + fileItems.size() + "].");
		this.doProcessFilesItems(fileItems, keyValueResult, request, response);
	}
	
	@Override
	protected void doCheckParameters(KeyValueResult keyValueResult) {
		// Do nothing.		
	}

	protected void doProcessFilesItems(List<FileItem> fileItems, KeyValueResult keyValueResult,final HttpServletRequest request, final HttpServletResponse response){
		FileItem uploadFileItem = null;
		for ( final FileItem fileItem : fileItems ) {
			if ( !fileItem.isFormField() ) {
				uploadFileItem = fileItem;
			}
		}		
		LOGGER.info("Process upload file item [" + uploadFileItem.getName() + "] with size [" + uploadFileItem.getSize() + "] bytes.");
		this.doProcess(uploadFileItem, keyValueResult, request, response);
	}

	@SuppressWarnings("unchecked")
	protected List<FileItem> getFilesItems(File temporaryDirectory, final HttpServletRequest request) {
		FileItemFactory factory = new DiskFileItemFactory(1024 * 1000, temporaryDirectory);
		ServletFileUpload upload = new ServletFileUpload(factory);
		List<FileItem> filesItems = null;
		try {
			filesItems = upload.parseRequest(request);
		} catch (FileUploadException e) {
			throw new NonBusinessException("Error occurred parsing request for upload file item.", e);
		}
		return filesItems;
	}

	protected File buildTemporaryDirectory(KeyValueResult keyValueResult) {
		String tempDirectory = "..\\";
		if(keyValueResult.containsResultFor("UPLOAD_TEMP_DIRECTORY")){
			tempDirectory = keyValueResult.getResultFor("UPLOAD_TEMP_DIRECTORY").toString();
		}

		File tempDir = new File(tempDirectory);
		if ( !tempDir.exists() ) {
			try {
				FileUtils.forceMkdir(tempDir);
			} catch (IOException e) {
				throw new NonBusinessException(e);
			}
		}
		return tempDir;
	}
}